const path = require('path');
const UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin');

function resolve(dir) {
  return path.join(__dirname, dir);
}

const isProd = process.env.NODE_ENV === 'production';
// 项目名称
const projectName = 'vue-demo-master';
const publicPath = isProd && projectName ? `/${projectName}/` : '/';

const distPath = path.resolve('./dist/build');

module.exports = {
  // 部署应用包时的基础 URL, 用法和 webpack 本身的 output.publicPath 一致
  // 此处配置文件打包的相对路径，默认情况下为 '/'，如果在生产环境有变动，可指定路径
  publicPath,
  // 打包后的文件目录，当运行 vue-cli-service build 时生成的生产环境构建文件的目录，目标目录在构建之前会被清除（构建时传入 --no-clean 可关闭该行为）
  outputDir: distPath,
  // 放置生成的静态资源(js、css、img、fonts)的目录
  assetsDir: isProd && projectName ? `${projectName}/static` : 'static',
  // 默认情况下，生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存
  filenameHashing: true,
  // 是否在保存的时候使用 'eslint-loader' 进行检查，有效值: true | false | 'error' 当设置为 'error' 时，检查出的错误会触发编译失败
  // 生产构建时禁用 eslint-loader
  lintOnSave: !isProd,
  // 如果不需要生产环境的 source map , 可以将其设置为 false 以加速生产环境构建
  productionSourceMap: false,
  // node_modules里的依赖默认是不会编译的,会导致es6语法在ie中的语法报错,
  // 所以需要在vue.config.js中使用transpileDependencies属性配置node_modules中指定哪些文件夹或文件需要编译.
  transpileDependencies: !isProd ? ['*'] : [],
  // css 配置
  css: {
    // 是否使用 css 分离插件 ExtractTextPlugin
    extract: isProd,
    // 是否开启 css source map
    sourceMap: false,
    // loaderOptions: {
    //   less: {
    //     modifyVars: {
    //       'primary-color': '#00a6c9',
    //       'link-color': '#00a6c9',
    //       // 'border-radius-base': '2px',
    //     },
    //     javascriptEnabled: true,
    //   },
    // },
  },

  // 调整内部的 webpack 配置
  chainWebpack: config => {
    config.resolve.alias
      .set('@', resolve('src'))
      .set('@assets', resolve('src/assets'))
      .set('@components', resolve('src/components'))
      .set('@views', resolve('src/views'))
      .set('@apis', resolve('src/apis'))
      .set('@store', resolve('src/store'));

    // 定义全局变量
    config.plugin('define').tap(args => [{
      ...args[0],
      'window.brand': JSON.stringify('vue'),
      'window.isDefine': JSON.stringify(true),
      'process.env': JSON.stringify(process.env),
      'process.env.WEBPACK_ENV': JSON.stringify(process.env.WEBPACK_ENV),
    }]);

    // 修改 html-webpack-plugin 参数
    config.plugin('html').tap(options => {
      options[0].title = 'vue-demo 后台管理系统';
      // options[0].cryptoPath = `${publicPath}js/crypto-js.js`;
      return options;
    });

    // 解决 ie11 兼容 ES6
    // config.entry('main').add('babel-polyfill');

    // 如果是生产环境
    if (isProd) {
      // 修改打包时 css 抽离后的 filename 及抽离所属目录
      config.plugin('extract-css').tap(() => [{
        filename: 'css/[name].[contenthash:8].css',
        chunkFilename: 'css/[name].[contenthash:8].css',
      }]);

      config.optimization.splitChunks({
        chunks: 'all',
        cacheGroups: {
          // antdvUI: {
          //   name: 'chunk-antdvUI',
          //   priority: 20,
          //   test: /[\\/]node_modules[\\/]_?ant-design-vue(.*)/,
          // },
          common: {
            name: 'common',
            chunks: 'all',
            minSize: 1,
            minChunks: 2,
            priority: 1,
          },
          vendor: {
            name: 'vendor',
            chunks: 'all',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
          },
        },
      });


      // svg-sprite-loader: 将 svg 图片以雪碧图的方式在项目中加载
      // config.module
      //   .rule('svg')
      //   .test(/\.svg$/)
      //   .include.add(resolve('src/assets/svg')) // 主要匹配 src/assets/svg
      //   .end()
      //   .use('svg-sprite-loader')
      //   .loader('svg-sprite-loader')
      //   .options({ symbolId: 'svg-[name]' }); // 参数配置

      // png、jpg 图片压缩； jpg 图片压缩图片质量变差
      // config.module
      //   .rule('images')
      //   .use('image-webpack-loader')
      //   .loader('image-webpack-loader')
      //   .options({ bypassOnDebug: true })
      //   .end();

      // 文件名称 hash 三种规则: hash chunkhash contenthash
      // config.output.filename('[name].[contenthash].js').end();
    }
  },

  /**
   * type: Object | Function
   *    - 对象时，和 webpack 本身配置方式一致，该对象将会被 webpack-merge 合并入最终的 webpack 配置
   *    - 函数时，直接在函数内部进行配置更改
   */
  // eslint-disable-next-line no-unused-vars
  configureWebpack: config => {
    const plugins = [];

    if (isProd) {
      plugins.push(
        // 去掉 console.log、debugger
        new UglifyJsWebpackPlugin({
          // 默认为 false
          sourceMap: false,
          uglifyOptions: {
            warnings: false,
            compress: {
              // eslint-disable-next-line camelcase
              drop_console: true,
              // eslint-disable-next-line camelcase
              drop_debugger: true,
              // eslint-disable-next-line camelcase
              pure_funcs: ['console.log'],
            },
          },
        }),
      );

      // gzip
      // plugins.push(
      //   new CompressionPlugin({
      //     filename: '[path].gz[query]',
      //     algorithm: 'gzip',
      //     test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'),
      //     threshold: 8192,
      //     mainRatio: 0.8,
      //   }),
      // );

      // 根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
      // plugins.push(new HashedModuleIdsPlugin());

      // 打包时 npm 包转 CDN
      // config.externals = [];
    }

    return { plugins };
  },

  pluginOptions: {
    // 配置全局 scss
    // 'style-resources-loader': {
    //   preprocessor: 'scss',
    //   patterns: [resolve('src/assets/scss/main.scss')],
    // },
  },

  // webpack-dev-server 相关配置
  devServer: {
    historyApiFallback: true,
    // noInfo: true,

    hot: true, // 热加载
    host: 'localhost', //ip地址
    port: 9000, //端口
    https: false, // false关闭https，true为开启
    open: false, // 自动打开浏览器
    // overlay: {
    //   warnings: false,
    //   errors: true,
    // },
    // 设置代理
    // proxy: {
    //   '/api': {
    //     /* 目标代理服务器地址 */
    //     target: 'http://localhost:3000',
    //     // 如果要代理 websockets
    //     ws: true,
    //     /* 允许跨域 */
    //     changeOrigin: true,
    //     // pathRewrite: {
    //     //   '^/api': ''
    //     // }
    //   },
    // },
    // before: app => {},
  },
};
